<?php

class AttachmentFileController extends Controller
{
	const SESSION_UPLOAD_FILES='files';
	
	/**
	 * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
	 * using two-column layout. See 'protected/views/layouts/column2.php'.
	 */
	public $layout='//layouts/column2';

	/**
	 * @return array action filters
	 */
	public function filters()
	{
		return array(
			'accessControl', // perform access control for CRUD operations
		);
	}

	/**
	 * Specifies the access control rules.
	 * This method is used by the 'accessControl' filter.
	 * @return array access control rules
	 */
	public function accessRules()
	{
		return array(
			array('allow', // only allow authenticated user to get access to the system.
				'actions'=>array('create','update','admin','delete','downLoad','batch','uploadFilesPlupload','uploadFilesInfo'),
				'users'=>array('@'),
			),
			array('deny',  // deny all users
				'users'=>array('*'),
			),
		);
	}

	/**
	 * Displays a particular model.
	 * @param integer $id the ID of the model to be displayed
	 */
/*	public function actionView($id)
	{
		$this->render('view',array(
			'model'=>$this->loadModel($id),
		));
	}*/

	/**
	 * Creates a new model.
	 * If creation is successful, the browser will be redirected to the 'view' page.
	 */
	public function actionCreate($attachmentId)
	{
		//check access control.
		$dealId = Attachment::model()->findByPk($attachmentId)->dealId;
		if(!Yii::app()->user->checkAccess('dealInfoAccess',array('dealId'=>$dealId)))
			throw new CHttpException(403,'You do not have permission to upload attachment file.');
		
		$model=new AttachmentFile;
		$model->attachmentId=$attachmentId;

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['AttachmentFile']))
		{
			$model->attributes=$_POST['AttachmentFile'];
			if($model->validate()){
				$file=CUploadedFile::getInstance($model, 'fileName');
				$fileName=$file->getName();
				$model->fileName=$fileName;
				
				$pos=strrpos($fileName,'.',-1);
				$mainFileName=substr($fileName, 0,$pos);
				$exFileName=substr($fileName, $pos+1);
				
				$model->storeFileName=preg_replace('/[^a-zA-Z0-9]/', '_', $mainFileName)
					.'.'.preg_replace('/[^a-zA-Z0-9]/', '_', $exFileName);
				
				if($model->save()){
					$savedModel=$this->loadModel($model->id);
					$savedModel->storeFileName=$model->id.'_'.$model->storeFileName;//update storeFileName;
					if ($savedModel->save()) {
						$this->_createFolderFor($savedModel);
						$file->saveAs(Yii::app()->params['attachmentFileLocation']
							.DIRECTORY_SEPARATOR.$savedModel->attachment->dealId
							.DIRECTORY_SEPARATOR.$savedModel->attachmentId
							.DIRECTORY_SEPARATOR.$savedModel->storeFileName
						);
						$this->redirect(array('attachment/view','id'=>$attachmentId));
					}
				}
			}
		}

		//$model->attachment=Attachment::model()->findByPk($attachmentId);
		$this->render('create',array(
			'model'=>$model,
		));
	}

	private function _createFolderFor($model){
		$base=Yii::app()->params['attachmentFileLocation'];
		if(!file_exists($base.DIRECTORY_SEPARATOR.$model->attachment->dealId)){
			mkdir($base.DIRECTORY_SEPARATOR.$model->attachment->dealId);
		}
		if(!file_exists($base.DIRECTORY_SEPARATOR.$model->attachment->dealId.DIRECTORY_SEPARATOR.$model->attachmentId)){
			mkdir($base.DIRECTORY_SEPARATOR.$model->attachment->dealId.DIRECTORY_SEPARATOR.$model->attachmentId);
		}
	}

	public function actionBatch($attachmentId)
	{
		//check access control.
		$dealId = Attachment::model()->findByPk($attachmentId)->dealId;
		if(!Yii::app()->user->checkAccess('dealInfoAccess',array('dealId'=>$dealId)))
			throw new CHttpException(403,'You do not have permission to upload attachment file.');
		
		$model=new AttachmentFile;
		$model->attachmentId=$attachmentId;

		//$model->attachment=Attachment::model()->findByPk($attachmentId);
		$this->render('batch',array(
			'model'=>$model,
		));
	}

	/**
	 * Updates a particular model.
	 * If update is successful, the browser will be redirected to the 'view' page.
	 * @param integer $id the ID of the model to be updated
	 */
	public function actionUpdate($id)
	{
		$model=$this->loadModel($id);
		
		//check access control.
		$dealId = $model->attachment->dealId;
		if(!Yii::app()->user->checkAccess('dealInfoAccess',array('dealId'=>$dealId)))
			throw new CHttpException(403,'You do not have permission to update information of the attachment file.');

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['AttachmentFile']))
		{
			$model->attributes=$_POST['AttachmentFile'];
			if($model->save())
				$this->redirect(array('attachment/view','id'=>$model->attachmentId));
		}

		$this->render('update',array(
			'model'=>$model,
		));
	}

	/**
	 * Deletes a particular model.
	 * If deletion is successful, the browser will be redirected to the 'admin' page.
	 * @param integer $id the ID of the model to be deleted
	 */
	public function actionDelete($id)
	{
		$model=$this->loadModel($id);
		
		//check access control.
		$dealId = $model->attachment->dealId;
		if(!Yii::app()->user->checkAccess('dealInfoAccess',array('dealId'=>$dealId)))
			throw new CHttpException(403,'You do not have permission to delete the attachment file.');
		
		if(Yii::app()->request->isPostRequest)
		{
			// we only allow deletion via POST request
			// delete the file
			@unlink(Yii::app()->params['attachmentFileLocation']
			.DIRECTORY_SEPARATOR.$model->attachment->dealId
			.DIRECTORY_SEPARATOR.$model->attachmentId
			.DIRECTORY_SEPARATOR.$model->storeFileName);
			
			// delete the record in db.
			$model->delete();

			// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
			/*if(!isset($_GET['ajax']))
				$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));*/
		}
		else
			throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
	}

	/**
	 * Lists all models.
	 */
/*	public function actionIndex()
	{
		$dataProvider=new CActiveDataProvider('AttachmentFile');
		$this->render('index',array(
			'dataProvider'=>$dataProvider,
		));
	}*/

	/**
	 * Manages all models.
	 */
/*	public function actionAdmin()
	{
		$model=new AttachmentFile('search');
		$model->unsetAttributes();  // clear any default values
		if(isset($_GET['AttachmentFile']))
			$model->attributes=$_GET['AttachmentFile'];

		$this->render('admin',array(
			'model'=>$model,
		));
	}*/

	/**
	 * Returns the data model based on the primary key given in the GET variable.
	 * If the data model is not found, an HTTP exception will be raised.
	 * @param integer the ID of the model to be loaded
	 * @return AttachmentFile
	 */
	public function loadModel($id)
	{
		$model=AttachmentFile::model()->findByPk((int)$id);
		if($model===null)
			throw new CHttpException(404,'The requested page does not exist.');
		return $model;
	}

	/**
	 * Performs the AJAX validation.
	 * @param CModel the model to be validated
	 */
/*	protected function performAjaxValidation($model)
	{
		if(isset($_POST['ajax']) && $_POST['ajax']==='attachment-file-form')
		{
			echo CActiveForm::validate($model);
			Yii::app()->end();
		}
	}*/
	
	public function actionDownload($id,$view=false){
		$model=$this->loadModel($id);
		
		//check access control.
		$dealId = $model->attachment->dealId;
		if(!Yii::app()->user->checkAccess('dealInfoAccess',array('dealId'=>$dealId)))
			throw new CHttpException(403,'You do not have permission to download the attachment file.');
		
		$filePath=Yii::app()->params['attachmentFileLocation']
			.DIRECTORY_SEPARATOR.$model->attachment->dealId
			.DIRECTORY_SEPARATOR.$model->attachmentId
			.DIRECTORY_SEPARATOR.$model->storeFileName;
		if(!$view){
			$model->fileName = str_replace(' ', '_', $model->fileName);
			header('Content-Type: application/octet-stream');
	    	header('Content-Disposition: attachment; filename='.$model->fileName);
		}else{
			header('Content-Type: '.CFileHelper::getMimeType($filePath));
		}
		readfile($filePath);
		exit;
	}

	public function actionUploadFilesPlupload()
	{
		// HTTP headers for no cache etc
		header('Content-type: text/plain; charset=UTF-8');
		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
		header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
		header("Cache-Control: no-store, no-cache, must-revalidate");
		header("Cache-Control: post-check=0, pre-check=0", false);
		header("Pragma: no-cache");

		// Settings
		$targetDir = Yii::app()->runtimePath . DIRECTORY_SEPARATOR . "plupload";
		$cleanupTargetDir = false; // Remove old files
		$maxFileAge = 60 * 60 * 24; // Temp file age in seconds, in this case 1 day

		// 5 minutes execution time
		@set_time_limit(5 * 60);
		// usleep(5000);

		// Get parameters
		$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
		$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
		$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';

		// Clean the fileName for security reasons
		$fileName = preg_replace('/[^\w\._\s]+/', '', $fileName);

		// Create target dir
		if (!file_exists($targetDir))
			@mkdir($targetDir);

		// Remove old temp files
		if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
			while (($file = readdir($dir)) !== false) {
				$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
				// Remove temp files if they are older than the max age
				if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
				@unlink($filePath);
			}

			closedir($dir);
		}else{
			throw new CHttpException (500, Yii::t('app', "Can't open temporary directory."));
		}

		// Look for the content type header
		if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
		$contentType = $_SERVER["HTTP_CONTENT_TYPE"];

		if (isset($_SERVER["CONTENT_TYPE"]))
		$contentType = $_SERVER["CONTENT_TYPE"];

		if (strpos($contentType, "multipart") !== false) {
			if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
				// Open temp file
				$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
				if ($out) {
					// Read binary input stream and append it to temp file
					$in = fopen($_FILES['file']['tmp_name'], "rb");

					if ($in) {
						while ($buff = fread($in, 4096))
						fwrite($out, $buff);
					} else
					throw new CHttpException (500, Yii::t('app', "Can't open input stream."));

					fclose($out);
					@unlink($_FILES['file']['tmp_name']);
				} else
				throw new CHttpException (500, Yii::t('app', "Can't open output stream."));
			} else
			throw new CHttpException (500, Yii::t('app', "Can't move uploaded file."));
		} else {
			// Open temp file
			$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
			if ($out) {
				// Read binary input stream and append it to temp file
				$in = fopen("php://input", "rb");

				if ($in) {
					while ($buff = fread($in, 4096))
					fwrite($out, $buff);
				} else
				throw new CHttpException (500, Yii::t('app', "Can't open input stream."));

				fclose($out);
			} else
			throw new CHttpException (500, Yii::t('app', "Can't open output stream."));
		}

		// After last chunk is received, process the file
		$fileId=substr($fileName, 0,strpos($fileName, '.'));
		$ret = array('fileId' => $fileId);
		if (intval($chunk) + 1 >= intval($chunks)) {
			// find out the actualy filename
			$originalname = $fileName;
			if (isset($_SERVER['HTTP_CONTENT_DISPOSITION'])) {
				$arr = array();
				preg_match('@^attachment; filename="([^"]+)"@',$_SERVER['HTTP_CONTENT_DISPOSITION'],$arr);
				if (isset($arr[1]))
				$originalname = $arr[1];
			}
			Yii::log("Uploaded file: ".$originalname.' Stored as '.$fileName);
			// store file info in session
			$session=Yii::app()->session;
			$sessionFileInfo=isset($session[self::SESSION_UPLOAD_FILES])?$session[self::SESSION_UPLOAD_FILES]:array();
			$sessionFileInfo[$fileId]=array(
				'path'=>$targetDir . DIRECTORY_SEPARATOR . $fileName,
				'name'=>$originalname,
				'time'=>date('Y-m-d h:i'),
			);
			foreach ($sessionFileInfo as $id=>$fileInfo) {
				if(!file_exists($fileInfo['path'])){
					// clean up outdated files
					unset($sessionFileInfo[$id]);
				}
			}
			$session[self::SESSION_UPLOAD_FILES]=$sessionFileInfo;
		}
		echo $fileId;
	}

	public function actionUploadFilesInfo($attachmentId){
		$session=Yii::app()->session;
		$sessionFileInfo=$session[self::SESSION_UPLOAD_FILES];
		$sessionFile=$sessionFileInfo[$_POST['id']];
		//		$sessionFileInfo[$_POST['id']]=array('path'=>$sessionFile['path'],
		//				'name'=>$_POST['name'],
		//				'time'=>$sessionFile['time'],
		//		);
		$model=new AttachmentFile('batch');
		$model->attachmentId=$attachmentId;
		$fileName=$_POST['name'];
		$model->fileName=$fileName;
		$pos=strrpos($fileName,'.',-1);
		$mainFileName=substr($fileName, 0,$pos);
		$exFileName=substr($fileName, $pos+1);
			
		$model->storeFileName=preg_replace('/[^a-zA-Z0-9]/', '_', $mainFileName)
		.'.'.preg_replace('/[^a-zA-Z0-9]/', '_', $exFileName);
		if($model->save()){
			$savedModel=$this->loadModel($model->id);
			$savedModel->storeFileName=$model->id.'_'.$model->storeFileName;//update storeFileName;
			if ($savedModel->save()) {
				$this->_createFolderFor($savedModel);
				rename($sessionFile['path'], Yii::app()->params['attachmentFileLocation']
				.DIRECTORY_SEPARATOR.$savedModel->attachment->dealId
				.DIRECTORY_SEPARATOR.$savedModel->attachmentId
				.DIRECTORY_SEPARATOR.$savedModel->storeFileName);
				unset($sessionFileInfo[$_POST['id']]);
				echo CJSON::encode($fileName);
				return;
			}
		}
		echo CJSON::encode("Error uploading: ".$fileName);
	}
}
